home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / NeoIntroTCL3.0 folder / TCL / NeoBench / Source / CNeoBenchDoc.cp < prev    next >
Encoding:
Text File  |  1994-09-02  |  17.4 KB  |  696 lines  |  [TEXT/KAHL]

  1. /****
  2.  * CNeoBenchDoc.c
  3.  *
  4.  *    Document methods for a typical application.
  5.  *
  6.  *  Copyright © 1990 Symantec Corporation.  All rights reserved.
  7.  *
  8.  ****/
  9.  
  10. #include "NeoTypes.h"
  11. #include "Global.h"
  12. #include "Commands.h"
  13. #include "CBartender.h"
  14. #include "CDecorator.h"
  15. #include "CDesktop.h"
  16. #include "CError.h"
  17. #include "CScrollPane.h"
  18. #include "CNeoBenchApp.h"
  19. #include "CNeoBenchDoc.h"
  20. #include "CNeoBenchPane.h"
  21. #include <Packages.h>
  22. #include <CWindow.h>
  23. #include <stdlib.h>
  24. #include CNeoDatabaseNativeH
  25. #include CNeoIndexIteratorH
  26. #include CNeoMetaClassH
  27. #include "CFiller.h"
  28.  
  29. #define    WINDNeoBench        500            /* Resource ID for WIND template */
  30.  
  31. extern    CBartender *    gBartender;        /* The menu handling object */
  32. extern    CDecorator *    gDecorator;        /* Window dressing object    */
  33. extern    CDesktop *        gDesktop;        /* The enclosure for all windows */
  34.  
  35. #ifdef qNeoThreads
  36. static short default_threads[kMaxPhase + 1] = { 1, 2, 2, 2, 2 };
  37. #endif
  38.  
  39. long gLoopOverhead;    // Timer Manager Overhead
  40.  
  41. /***
  42.  * CNeoBenchDoc
  43.  *
  44.  *    This is your document's initialization method.
  45.  *    If your document has its own instance variables, initialize
  46.  *    them here.
  47.  *
  48.  *    The least you need to do is invoke the default method.
  49.  *
  50.  ***/
  51.  
  52. CNeoBenchDoc::CNeoBenchDoc(const Boolean aPrintable, const Boolean aNewDatabase, const Boolean aRemote)
  53.     : CNeoDocTCL(kNeoBenchSig, kNeoBenchFileType, aPrintable, aNewDatabase)
  54. {
  55.     short    index, j;
  56.  
  57.     /**
  58.      ** Set the button state flag
  59.      **/
  60.     fState = kStop;
  61.     fRefresh = TRUE;
  62.  
  63. #ifdef qNeoThreads
  64.     fThreadCount = 0;
  65. #endif
  66.  
  67.     fPhase = kNoPhase;            /* No phase yet    */
  68.     fIterator = nil;
  69.  
  70.     // These three values are the running values that change
  71.     col_index = kMinCol;
  72.     for (index = kMinCol; index <= kMinCol; index++)
  73.         col_value[index] = 0;
  74.  
  75.     //
  76.     // Init the fields in the array.  The default values
  77.     // will be coming from the text in the TextEdit boxes.
  78.     //
  79.  
  80.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  81.         fPhaseInfo[index].dirty = FALSE;
  82. #ifdef qNeoThreads
  83.         NeoAssert(default_threads[index] <= kMaxThreads);
  84.         fPhaseInfo[index].threadCount = default_threads[index];
  85. #endif
  86.         fPhaseInfo[index].target = 0;
  87.         fPhaseInfo[index].done = 0;
  88.         fPhaseInfo[index].committed = 0;
  89.         fPhaseInfo[index].soFar = 0;
  90.     }
  91.  
  92.     srand((unsigned int)clock());
  93. }
  94.  
  95. /***
  96.  * buildWindow
  97.  *
  98.  *    This is the auxiliary window-building method that the
  99.  *    NewFile() and OpenFile() methods use to create a window.
  100.  *
  101.  *    In this implementation, the argument is the data to display.
  102.  *
  103.  ***/
  104.  
  105. void CNeoBenchDoc::buildWindow(void)
  106. {
  107.     CScrollPane        *theScrollPane;
  108.     CNeoBenchPane    *theMainPane;
  109.     Rect            windRect;
  110.  
  111.         /**
  112.          **    First create the window and initialize
  113.          **    it. The first argument is the resource ID
  114.          **    of the window. The second argument specifies
  115.          **    whether the window is a floating window.
  116.          **    The third argument is the window's enclosure; it
  117.          **    should always be gDesktop. The last argument is
  118.          **    the window's supervisor in the Chain of Command;
  119.          **    it should always be the Document object.
  120.          **
  121.          **/
  122.  
  123.     itsWindow = new CWindow();
  124.     itsWindow->IWindow(WINDNeoBench, FALSE, gDesktop, this);
  125.  
  126.         /**
  127.          ** Set the Min and Max value the window can be resized.
  128.          **  Note that we really don't want the user to resize it
  129.          **  so we make the min and max numbers the same.
  130.          **/
  131.     itsWindow->ChangeSize(508, 299);
  132.     SetRect(&windRect, 508, 299, 508, 299);
  133.     itsWindow->SetSizeRect(&windRect);
  134.  
  135.         /**
  136.          ** We are just creating a fixed pane that sits in the
  137.          ** window.   And this will become like a modeless dialog
  138.          **/
  139.  
  140.     theMainPane = new(CNeoBenchPane);
  141.     theMainPane->INeoBenchPane(itsWindow, this, 508, 299, 0, 0, sizFIXEDLEFT, sizFIXEDTOP);
  142.     itsMainPane = theMainPane;
  143.     itsGopher = theMainPane;
  144.  
  145.         /**
  146.          ** Use CenterWindow to center the window in the middle
  147.          ** of the screen.
  148.          **/
  149.  
  150.     gDecorator->CenterWindow(itsWindow);
  151. }
  152.  
  153. Boolean    CNeoBenchDoc::Close(Boolean aQuitting)
  154. {
  155. #ifdef qNeoThreads
  156.         killThreads();
  157. #endif
  158.  
  159.     delete fIterator;
  160.     fIterator = nil;
  161.  
  162.     return inherited::Close(aQuitting);
  163. }
  164.  
  165.  
  166. /***
  167.  * DoCommand
  168.  *
  169.  *    This is the heart of your document.
  170.  *    In this method, you handle all the commands your document
  171.  *    deals with.
  172.  *
  173.  *    Be sure to call the default method to handle the standard
  174.  *    document commands: cmdClose, cmdSave, cmdSaveAs, cmdRevert,
  175.  *    cmdPageSetup, cmdPrint, and cmdUndo. To change the way these
  176.  *    commands are handled, override the appropriate methods instead
  177.  *    of handling them here.
  178.  *
  179.  ***/
  180.  
  181. void CNeoBenchDoc::DoCommand(long theCommand)
  182. {
  183.     short    index;
  184.     long    minPhase;
  185.  
  186.     switch (theCommand) {
  187.     case cmdGO:
  188.         //---------------------------------------------------
  189.         // Get the numbers from the Dialog box,  and update
  190.         // the fields with the values of the numbers the
  191.         // user has typed in.   Also,  if the user has typed
  192.         // in out of range numbers,   correct them.
  193.         //---------------------------------------------------
  194.         getTargetTotals();
  195.  
  196.         //---------------------------------------------------
  197.         // Set the "fPhase" value to kMinPhase to start the
  198.         // Dawdling process to proceed
  199.         //---------------------------------------------------
  200.         for (index = kMinPhase;  index <= kMaxPhase; index++) {
  201.             fPhaseInfo[index].done = 0;
  202.             fPhaseInfo[index].delta = 0;
  203.             fPhaseInfo[index].soFar = 0;
  204.         }
  205.  
  206.         fPhaseInfo[kInsert].delta = ((CNeoDatabase *)itsFile)->getObjectCount(kFillerID, FALSE);
  207.         if (fPhaseInfo[kInsert].delta)
  208.             ((CNeoBenchPane *)itsMainPane)->UpdateCol(kInsert, kSoFar, fPhaseInfo[kInsert].delta);
  209.  
  210.         if (fPhaseInfo[kInsert].delta < fPhaseInfo[kInsert].target)
  211.             fPhase = kMinPhase;
  212.         else
  213.             fPhase = kRandomly;
  214.         break;
  215.  
  216.     case cmdSTOP:
  217.         fPhase = 0;
  218.         break;
  219.  
  220.     default:
  221.         inherited::DoCommand(theCommand);
  222.         break;
  223.     }
  224. }
  225.  
  226. /***
  227.  * NewFile
  228.  *
  229.  *    When the user chooses New from the File menu, the createDocument
  230.  *    method in your application will call the newly created document's
  231.  *    NewFile message.
  232.  *
  233.  *    This method should begin by calling inherited. After that it might
  234.  *    want to title the window and set the default name which will appear
  235.  *    in the standard get file dialog. NeoBench calls DoSaveFileAs just
  236.  *    so the user doesn't have to choose the Save menu item. Your
  237.  *    application may decide otherwise.
  238.  *
  239.  ***/
  240. void CNeoBenchDoc::NewFile(void)
  241. {
  242.     inherited::NewFile();
  243.  
  244.     // Append an index number to the default name of the window.
  245.     itsWindow->SetTitle("\pNeoAccess");
  246.  
  247.     // Set the default name which appears in the get file dialog.
  248.     NeoStringCopy("\pNeoBench Results", itsFile->name);
  249.     DoSaveFileAs();
  250. }
  251.  
  252. /***
  253.  * OpenFile
  254.  *
  255.  *    When the user chooses Open… from the File menu, the OpenDocument
  256.  *    method in your application class will let the user choose a file
  257.  *    and then send a newly created document this message. The information
  258.  *    about the file is in the SFReply record.
  259.  *
  260.  ***/
  261. void CNeoBenchDoc::OpenFile(SFReply *macSFReply)
  262. {
  263.     fOpenMode = fsRdWrPerm;
  264.     inherited::OpenFile(macSFReply);
  265.  
  266.     fPhaseInfo[kInsert].delta = ((CNeoDatabase *)itsFile)->getObjectCount(kFillerID, FALSE);
  267.     if (fPhaseInfo[kInsert].delta)
  268.         ((CNeoBenchPane *)itsMainPane)->UpdateCol(kInsert, kSoFar, fPhaseInfo[kInsert].delta);
  269.  
  270.     itsWindow->Select();            /* Don't forget to make the window active */
  271. }
  272.  
  273. /******************************************************************************
  274.  Dawdle
  275.  ******************************************************************************/
  276.  
  277. void CNeoBenchDoc::Dawdle(long *maxSleep)
  278. {
  279.     short                index;
  280.     long                loops        = 0;
  281.     CNeoBenchPane *        pane;
  282.     CNeoDatabaseTCL *    database    = getDatabase();
  283.  
  284.     NeoUsed(loops);
  285.  
  286. #ifndef qNeoThreads
  287.     TMTask            timer;
  288.  
  289.     if (fState == kStart)
  290.         doSomeWork(fPhase, &timer);
  291. #endif
  292.  
  293.     pane = (CNeoBenchPane *)itsMainPane;
  294.     NeoAssert(pane);
  295.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  296.         if (fPhaseInfo[index].dirty) {
  297.             pane->UpdateCol(index, kSoFar, fPhaseInfo[index].delta + fPhaseInfo[index].committed);
  298.             pane->UpdateCol(index, kPerRecord, (fPhaseInfo[index].soFar / (fPhaseInfo[index].committed ? fPhaseInfo[index].committed : 1)));
  299.             pane->UpdateCol(index, kTotal, fPhaseInfo[index].soFar);
  300.             fPhaseInfo[index].dirty = FALSE;
  301.         }
  302.         fRefresh = FALSE;
  303.     }
  304.  
  305.     if (fPhase > kMaxPhase)
  306.         setState(kStop);
  307.  
  308.     if (fPhase == kNoPhase &&
  309.         database->isOpen()) {
  310.         database->commit(TRUE);
  311.         setDirty(FALSE);
  312.     }
  313.  
  314. #ifdef qNeoThreads
  315.     loops = 0;
  316.     while (!fRefresh) {
  317.         CNeoThreadNative::Yield();
  318. #ifdef qNeoDebug
  319.         loops++;
  320.         if (loops > 1000) {
  321.             loops = 0;
  322.             break;
  323.         }
  324. #endif
  325.     }
  326. #endif
  327. }
  328.  
  329. /******************************************************************************
  330.  Dawdle
  331.  ******************************************************************************/
  332.  
  333. void CNeoBenchDoc::doSomeWork(const short aPhase, TMTask *aTimer)
  334. {
  335.     long            done;
  336.     long            IveDone        = 0;
  337.     long            delta;
  338.     long            quantum;
  339.     NeoID            id;
  340.     CNeoPersist *    object;
  341.     CNeoDatabase *    oldDatabase    = gNeoDatabase;
  342.     CNeoDatabase *    database    = getDatabase();
  343.     TMTask            updateTask;
  344.  
  345. #ifdef qNeoThreads
  346.     quantum = 500 * fPhaseInfo[aPhase].threadCount;
  347. #else
  348.     quantum = 500;
  349. #endif
  350.     if (fPhaseInfo[aPhase].delta + fPhaseInfo[aPhase].done < fPhaseInfo[aPhase].target) {
  351.         gNeoDatabase = database;
  352.  
  353.         updateTask.tmAddr = nil;
  354.         updateTask.qType = 0;
  355.         updateTask.tmCount = 0;
  356.         updateTask.tmWakeUp = 0;
  357.         updateTask.tmReserved = 0;
  358.         InsXTime((QElem *)&updateTask);
  359.         PrimeTime((QElem *)&updateTask, quantum);
  360.  
  361.         aTimer->tmAddr = nil;
  362.         aTimer->qType = 0;
  363.         aTimer->tmCount = 0;
  364.         aTimer->tmWakeUp = 0;
  365.         aTimer->tmReserved = 0;
  366.         InsXTime((QElem *)aTimer);
  367.         PrimeTime((QElem *)aTimer, k30MicroMinutes);
  368.     
  369.         while ((updateTask.qType&0x8000) &&
  370.                (fPhaseInfo[aPhase].delta + fPhaseInfo[aPhase].done < fPhaseInfo[aPhase].target)) {
  371.     
  372.             fPhaseInfo[aPhase].done++;
  373.             IveDone++;
  374.  
  375.             switch (aPhase) {
  376.             case    kInsert:
  377.                 /*------------------------------------------------------*/
  378.                 /* Perform the code for record insertion sequence         */
  379.                 /*------------------------------------------------------*/
  380.                 object = new CFiller;
  381.                 FailNIL(object);
  382.                 delta = fPhaseInfo[kInsert].delta;
  383.                 done = fPhaseInfo[kInsert].done;
  384.                 object->fID = delta + done;
  385.                 database->addObject(object);
  386.                 object->unrefer();
  387.                 if (delta + done == fPhaseInfo[kInsert].target) {
  388.                     if (database->isOpen())
  389.                         database->commit(FALSE);
  390.                         setDirty(FALSE);
  391.                 }
  392.                 break;
  393.  
  394.             case    kRandomly:
  395.                 /*------------------------------------------------------*/
  396.                 /* Perform the code for randomly searching sequence     */
  397.                 /*------------------------------------------------------*/
  398.                 id = (rand()&0x7FFFFFFF) % fPhaseInfo[kInsert].target;
  399.                 if (!id)
  400.                     id = fPhaseInfo[kInsert].target / 2;
  401.                 object = (CFiller *)CFiller::FindByID(database, kFillerID, id, FALSE, nil, nil);
  402.                 NeoAssert(object);
  403.                 object->unrefer();
  404.                 break;
  405.  
  406.             case    kSerially:
  407.                 /*------------------------------------------------------*/
  408.                 /* Serially iterate over a class of objects                */
  409.                 /*------------------------------------------------------*/
  410.                 if (fIterator) {
  411.                     object = fIterator->nextObject();
  412.                     if (!object) {
  413.                         fIterator->reset();
  414.                         object = fIterator->currentObject();
  415.                     }
  416.                 }
  417.                 else {
  418.                     fIterator = new CNeoIndexIterator(database, kFillerID, nil, FALSE, FALSE);
  419.                     object = fIterator->currentObject();
  420.                 }
  421.                 NeoAssert(object);
  422.                 break;
  423.  
  424.             case    kChange:
  425.                 /*------------------------------------------------------*/
  426.                 /* Perform the code for Change sequence here            */
  427.                 /*------------------------------------------------------*/
  428.                 if (fIterator) {
  429.                     object = fIterator->nextObject();
  430.                     if (!object) {
  431.                         fIterator->reset();
  432.                         object = fIterator->currentObject();
  433.                     }
  434.                 }
  435.                 else {
  436.                     fIterator = new CNeoIndexIterator(database, kFillerID);
  437.                     object = fIterator->currentObject();
  438.                 }
  439.                 NeoAssert(object);
  440.                 object->autoReferTo();
  441.                 object->setDirty();
  442.                 object->autoUnrefer();
  443.                 database->setDirty();
  444.                 break;
  445.  
  446.             case    kDelete:
  447.                 /*------------------------------------------------------*/
  448.                 /* Perform the code for Delete sequencing here            */
  449.                 /*------------------------------------------------------*/
  450.                 if (!fIterator)
  451.                     fIterator = new CNeoIndexIterator(database, kFillerID);
  452.                 object = fIterator->currentObject();
  453.                 NeoAssert(object);
  454.                 object->autoReferTo();
  455.                 fIterator->removeCurrent();
  456.                 object->autoUnrefer();
  457.                 break;
  458.             }
  459.         }
  460.  
  461.         if (database->isOpen() &&
  462.             database->isDirty() &&
  463.             CNeoPersist::FCacheUsed > (CNeoPersist::FCacheSize>>1)) {
  464.             database->commit(FALSE);
  465.             database->setDirty(FALSE);
  466.         }
  467.  
  468.         RmvTime((QElem *)aTimer);
  469.         RmvTime((QElem *)&updateTask);
  470.  
  471.         if (aTimer->tmCount > 0)
  472.             fPhaseInfo[aPhase].soFar += -(k30MicroMinutes + aTimer->tmCount * 1000) - gLoopOverhead;
  473.         else
  474.             fPhaseInfo[aPhase].soFar += -(k30MicroMinutes - aTimer->tmCount) - gLoopOverhead;
  475.         fPhaseInfo[aPhase].committed += IveDone;
  476.         fPhaseInfo[aPhase].dirty = TRUE;
  477.  
  478.         gNeoDatabase = oldDatabase;
  479.     }
  480.     else {
  481.         setPhase(aPhase +1);
  482.         if (fIterator) {
  483.             fIterator->setForward(!fIterator->isForward());
  484.             fIterator->reset();
  485.         }
  486.     }
  487. }
  488.  
  489. /****************************************************************************
  490.   getTargetTotals - This method gets the target totals from the TextBoxes
  491.   in the main dialog for each of the 5 phases.    If there is any of the
  492.   totals that are out of range,   the text in the TextBoxes will be adjusted
  493.   to be within range.
  494. *****************************************************************************/
  495. void    CNeoBenchDoc::getTargetTotals(void)
  496. {
  497.     short    index;
  498.     CNeoBenchPane *pane;
  499.  
  500.     pane = (CNeoBenchPane *)itsMainPane;
  501.  
  502.     // For each of the phases,   get the info into the structure.
  503.  
  504.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  505.         fPhaseInfo[index].target = pane->GetTotalNum(index);
  506.     }
  507. }
  508.  
  509. Boolean CNeoBenchDoc::getState(void)
  510. {
  511.     return fState;
  512. }
  513.  
  514. #ifdef qNeoThreads
  515. void CNeoBenchDoc::killThreads(void)
  516. {
  517.     short    index;
  518.  
  519.     for (index = 0; index < kMaxThreads; index++) {
  520.         if (fThreadInfo[index].state == kAlive) {
  521.             NeoAssert(fThreadInfo[index].thread);
  522.             fThreadInfo[index].state = kDie;
  523.             CNeoThreadNative::Yield(fThreadInfo[index].thread);
  524.             fThreadInfo[index].thread = nil;
  525.         }
  526.     }
  527. }
  528. #endif
  529.  
  530. void CNeoBenchDoc::setState(const Boolean aState)
  531. {
  532.     short    index;
  533.     short    phase;
  534.  
  535.     if (aState == kStop) {
  536. #ifdef qNeoThreads
  537.         killThreads();
  538. #endif
  539.         phase = kNoPhase;
  540.     }
  541.     else {
  542.         getTargetTotals();
  543.         for (index = kMinPhase;  index <= kMaxPhase; index++) {
  544.             fPhaseInfo[index].done = 0;
  545.             fPhaseInfo[index].committed = 0;
  546.             fPhaseInfo[index].delta = 0;
  547.             fPhaseInfo[index].soFar = 0;
  548.         }
  549.  
  550.         fPhaseInfo[kInsert].delta = getDatabase()->getObjectCount(kFillerID, TRUE);
  551.         if (fPhaseInfo[kInsert].delta)
  552.             ((CNeoBenchPane *)itsMainPane)->UpdateCol(kInsert, kSoFar, fPhaseInfo[kInsert].delta);
  553.  
  554.         if (fPhaseInfo[kInsert].delta < fPhaseInfo[kInsert].target)
  555.             phase = kMinPhase;
  556.         else
  557.             phase = kRandomly;
  558.     }
  559.  
  560.     fState = aState;
  561.  
  562.     setPhase(phase);
  563. }
  564.  
  565. void CNeoBenchDoc::setPhase(const short aPhase)
  566. {
  567. #ifdef qNeoThreads
  568.     short    index;
  569.     short    count;
  570.  
  571.     if (aPhase >= kMinPhase &&
  572.         aPhase <= kMaxPhase)
  573.         count = fPhaseInfo[aPhase].threadCount;
  574.     else
  575.         count = 0;
  576.  
  577.     for (index = 0; index < count; index++) {
  578.         fThreadInfo[index].document = this;
  579.         fThreadInfo[index].phase = aPhase;
  580.         fThreadInfo[index].state = kAlive;
  581.         if (index >= fThreadCount) {
  582.             fThreadInfo[index].thread = new CBenchThread(&fThreadInfo[index]);
  583.             fThreadCount++;
  584.             fThreadInfo[index].thread->resume();
  585.         }
  586.     }
  587.  
  588.     for (index = fThreadCount; index > count; index--)
  589.         fThreadInfo[index].state = kDie;
  590. #endif
  591.  
  592.     fPhase = aPhase;
  593. }
  594.  
  595. void CNeoBenchDoc::ProviderChanged(CCollaborator *aProvider, long aReason, void* aParam)
  596. {
  597.     short            loops;
  598.     Size            size;
  599.     CNeoPersist *    object;
  600.     CNeoPersist *    parent;
  601.  
  602.     switch (aReason) {
  603.     case NeoAppNeedMemory:
  604.         size = (Size)aParam;
  605.         if (itsFile &&
  606.             (Size)aParam) {
  607.  
  608.             if (dirty) {
  609.                 ((CNeoDatabase *)itsFile)->commit(FALSE);
  610.                 dirty = FALSE;
  611.             }
  612.  
  613.             if (fPhase == kRandomly) {
  614.                 loops = 1;
  615.                 do {
  616.                     CNeoDatabase::FPurgeLevel = loops;
  617.                     CNeoDatabase::FPurgeMin = fPhaseInfo[kInsert].target / 16;
  618.                     CNeoDatabase::FPurgeDelta = CNeoDatabase::FPurgeMin / 2;
  619.                     loops++;
  620.                 } while (!((CNeoDatabase *)itsFile)->purge(size) &&
  621.                     MaxBlock() < size);
  622.                 return;
  623.             }
  624.             if (fPhase == kInsert)
  625.                 CNeoDatabase::FPurgeMin = 2000;
  626.             else
  627.                 CNeoDatabase::FPurgeMin = 200;
  628.             CNeoDatabase::FPurgeDelta = CNeoDatabase::FPurgeMin / 4;
  629.             CNeoDatabase::FPurgeLevel = 3;
  630.             ((CNeoDatabase *)itsFile)->purge(size);
  631.             if (MaxBlock() < size)
  632.                 ((CNeoDatabase *)itsFile)->purge(size);
  633.         }
  634.         break;
  635.  
  636.     default:
  637.         inherited::ProviderChanged(aProvider, aReason, aParam);
  638.         break;
  639.     }
  640. }
  641.  
  642. #ifdef qNeoThreads
  643. CBenchThread::CBenchThread(ThreadInfo *aInfo, const NeoThreadType aType, void **aArg, const Size aStackSize, const NeoThreadOptions aOptions)
  644.     : CNeoThreadNative(aType, aArg, aStackSize, aOptions)
  645. {
  646.     fSetTimer = FALSE;
  647.     fInfo = aInfo;
  648. }
  649.  
  650. long CBenchThread::run(void)
  651. {
  652.     while (fInfo->state == kAlive) {
  653.         fInfo->document->doSomeWork(fInfo->phase, &fTimer);
  654.     
  655.         Yield();
  656.     }
  657.  
  658.     fInfo->thread = nil;
  659.  
  660.     return fResult;
  661. }
  662.  
  663. // ---------------------------------------------------------------------------
  664. //        • handleSwapIn
  665. // ---------------------------------------------------------------------------
  666. //    Callback to the Thread Manager.
  667. //    
  668. void CBenchThread::handleSwapIn(void)
  669. {
  670.     inherited::handleSwapIn();
  671.  
  672.     // turn timers back on
  673.     if (fSetTimer) {
  674.         InsXTime((QElem *)&fTimer);
  675.         PrimeTime((QElem *)&fTimer, 0);
  676.     }
  677. }
  678.  
  679. // ---------------------------------------------------------------------------
  680. //        • handleSwapOut
  681. // ---------------------------------------------------------------------------
  682. //    Callback to the Thread Manager.
  683. //    
  684. void CBenchThread::handleSwapOut(void)
  685. {
  686.     // turn timers off
  687.     fSetTimer = fTimer.qType&0x8000;
  688.     if (fSetTimer)
  689.         RmvTime((QElem *)&fTimer);
  690.  
  691.     inherited::handleSwapOut();
  692. }
  693.  
  694. #endif
  695.  
  696.